import sys
from PyQt5.QtWidgets import QApplication, QMessageBox
from PyQt5.QtCore import Qt, QObject, QTimer, QSize
from PyQt5.QtGui import QIcon
from importlib import metadata
from keyboard_listener import HotkeyListener
from config_manager import config
import os
import traceback

# 添加全局快捷键处理器


class GlobalHotkeyHandler(QObject):
    def __init__(self, app_launcher):
        super().__init__()
        self.app_launcher = app_launcher
        self.hotkey_listener = HotkeyListener(config.hotkey)

        # 连接信号到面板显示/隐藏功能
        self.hotkey_listener.hotkey_triggered.connect(
            self._safe_toggle_panel)

        # 将引用保存到app_launcher中以便于访问
        app_launcher.hotkey_handler = self

        # 启动监听
        self.hotkey_listener.start()

    def _safe_toggle_panel(self):
        """安全地切换面板显示状态，确保在主线程中执行"""
        try:
            print("热键触发，切换面板")
            # 确保在主线程中执行，使用QTimer
            QTimer.singleShot(0, self._do_toggle_panel)
        except Exception as e:
            print(f"安排切换面板时出错: {e}")
            import traceback
            traceback.print_exc()

    def _do_toggle_panel(self):
        """实际执行面板切换"""
        try:
            # 确保面板存在
            if not hasattr(self.app_launcher, 'shortcutsPanel') or self.app_launcher.shortcutsPanel is None:
                print("面板不存在，正在创建...")
                from app_launcher_fluent import ShortcutsPanel
                self.app_launcher.shortcutsPanel = ShortcutsPanel()

            # 直接调用toggleShortcutsPanel方法进行处理
            self.app_launcher.toggleShortcutsPanel()
        except Exception as e:
            print(f"切换面板时出错: {e}")
            import traceback
            traceback.print_exc()

    def update_hotkey(self, new_hotkey):
        self.hotkey_listener.update_hotkey(new_hotkey)


def check_dependencies():
    """检查依赖项及其版本"""
    required = {
        'PyQt5': '5.15.0',
        'PyQt-Fluent-Widgets': '1.2.0',
        'Pillow': '8.0.0',
        'pywin32': '300',
        'pynput': '1.7.0'  # 添加pynput依赖
    }

    issues = []

    for package, min_version in required.items():
        try:
            version = metadata.version(package)
            print(f"✓ {package} v{version} 已安装")
        except metadata.PackageNotFoundError:
            issues.append(f"未安装 {package}")
            print(f"✗ {package} 未安装")
        except Exception as e:
            issues.append(f"检查 {package} 时出错: {e}")
            print(f"? {package} 检查出错: {e}")

    return issues


if __name__ == "__main__":
    try:
        # 启用更详细的异常信息

        # sys.excepthook = lambda exctype, value, tb: print(
        #     ''.join(traceback.format_exception(exctype, value, tb)))

        # 检查依赖项
        issues = check_dependencies()

        app = QApplication(sys.argv)
        app.setQuitOnLastWindowClosed(False)  # 关闭最后一个窗口时不退出

        # 设置全局应用程序属性，确保悬浮窗总是在最前面
        app.setAttribute(Qt.AA_UseHighDpiPixmaps, True)  # 使用高DPI图标

        # 创建并设置应用图标 - 使用assets/app.ico
        icon_path = os.path.join(os.path.dirname(
            os.path.abspath(__file__)), "assets/app.ico")
        app_icon = QIcon(icon_path)
        app.setWindowIcon(app_icon)

        # 如果有依赖问题，显示警告但继续运行
        if issues:
            message = "检测到以下问题，程序可能无法正常运行：\n• " + "\n• ".join(issues)
            print(message)

        # 延迟导入以确保在显示警告后再尝试导入
        from app_launcher_fluent import AppLauncherFluent
        window = AppLauncherFluent()

        # 初始化全局快捷键处理器 - 放在窗口创建后
        hotkey_handler = GlobalHotkeyHandler(window)

        # 设置悬浮按钮图标为圆形app.ico
        if hasattr(window, 'floatButton'):
            window.floatButton.setIcon(app_icon)
            # 确保悬浮按钮显示为圆形
            if hasattr(window.floatButton, 'setIconSize'):
                # 设置合适的图标大小以保持圆形显示
                window.floatButton.setIconSize(QtCore.QSize(32, 32))
            # 尝试设置圆形样式
            window.floatButton.setStyleSheet("border-radius: 16px;")

        # 只显示悬浮按钮，不显示主窗口
        window.show()

        sys.exit(app.exec_())
    except Exception as e:
        print(f"程序启动时出错: {e}")
        traceback.print_exc()

        # 如果GUI已经启动，尝试显示错误对话框
        try:
            if 'app' in locals():
                QMessageBox.critical(None, "启动错误", f"程序启动失败: {e}")
        except:
            pass
